package com.marvels.approve.loan.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.marvels.approve.common.service.McamLoanApplyInfoCommonService;
import com.marvels.approve.consum.ApproveConsumerFinancialApi;
import com.marvels.approve.loan.dao.IMcamLoanApplyInfoDao;
import com.marvels.approve.loan.dto.FeeRateDTO;
import com.marvels.approve.loan.dto.LoanAfterInfoDTO;
import com.marvels.approve.loan.dto.LoanForUploadConditionDto;
import com.marvels.approve.loan.dto.McamLoanApplyInfoDTO;
import com.marvels.approve.loan.dto.McfeLendingProcess;
import com.marvels.approve.loan.dto.McfeLendingProcessLog;
import com.marvels.approve.loan.service.LoanApplicationService;
import com.marvels.common.constants.LoanStateConstant;
import com.marvels.common.dto.MarvelsResultDTO;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.exception.MarvelsErrorCode;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.GenerateReqNoUtils;
import com.marvels.common.utils.MarvelsLogUtil;

@Service
public class LoanApplicationImpl implements LoanApplicationService {

	@Autowired
	private ApproveConsumerFinancialApi consumerFinancialApi;

	@Autowired
	private IMcamLoanApplyInfoDao iMcamLoanApplyInfoDao;

	@Autowired
	private McamLoanApplyInfoCommonService mcamLoanApplyInfoCommonService;
	
	@Override
	public MarvelsResultDTO applyLoanUploadDeal(Workbook workbook) throws MarvelsBusinessException{
		Sheet sheet = workbook.getSheetAt(0);// 获取第一个sheet
		String loanIds = "";// 将loan返回前端 做申请用
		int colNum = sheet.getLastRowNum();// 总行数 不包括标题内容
		BigDecimal decimal = new BigDecimal("0");
		Map<String, Object> data = new HashMap<>();
		int successCount = 0;
		if (colNum < 1) {// 不能少于2条(不包含标题)
			throw new MarvelsBusinessException("上传数据不能为空");
		}
		if (colNum > 800) {// 不能多于800条
			throw new MarvelsBusinessException("上传数据不能多于800条");
		}
		List<LoanForUploadConditionDto> list = new ArrayList<>();
		for (int i = 1; i <= colNum; i++) {
			Row rows = sheet.getRow(i); // 获取总行号
			if (rows.getCell(0) == null) {
				continue;
			}
			rows.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
			rows.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
			rows.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
			rows.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
			String custName = rows.getCell(0).getStringCellValue();// 获得第i行第1列信息
																	// 用户姓名
			String custIdNumber = rows.getCell(1).getStringCellValue();// 获得第i行第2列信息
																		// 用户身份证
			String applyAmount = rows.getCell(2).getStringCellValue();// 获得第i行第3列信息
																		// //申请金额
			String terms = rows.getCell(3).getStringCellValue();// 获得第i行第4列信息
																// 申请期数 //申请期数
			// 验证导入的信息是否在进件表中存在
			LoanForUploadConditionDto loanForUploadConditionDto = new LoanForUploadConditionDto();
			loanForUploadConditionDto.setApplyAmount(applyAmount);
			loanForUploadConditionDto.setCustIdNumber(custIdNumber);
			loanForUploadConditionDto.setCustName(custName);
			loanForUploadConditionDto.setTerms(terms);
			McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = iMcamLoanApplyInfoDao
					.selectByUploadCondition(loanForUploadConditionDto);
			if (mcamLoanApplyInfoDTO != null) {
				loanIds = mcamLoanApplyInfoDTO.getLoanId() + "," + loanIds;
				decimal = decimal.add(new BigDecimal(applyAmount));
				successCount++;
			} else {
				list.add(loanForUploadConditionDto);
			}

		}
		data.put("failData", list);
		data.put("sumAct", decimal.setScale(2, BigDecimal.ROUND_HALF_UP));// 四舍五入
																			// 保留两位小数
		data.put("loanIds", loanIds);
		data.put("successCount", successCount);
		return MarvelsResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), MarvelsErrorCode.SUCCESS.getDesc(),
				data);
	}

	@Override
	@Transactional(timeout = 100 ,rollbackFor=Exception.class)
	public MarvelsResultDTO executeLoanApply(String loands) throws MarvelsBusinessException {
		if (StringUtils.isEmpty(loands)) {
			throw new MarvelsBusinessException("进件单号不能为空");
		}
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().info(">>>>>>>获取token为空");
		}
		List<String> loanList = Arrays.asList(loands.substring(0, loands.length()).split(","));
		for (String loanId : loanList) {
			// 加锁 避免重复插入数据
			String key = "LOAN_APPLY_" + loanId;
			boolean isNotLock=false;
			try {
				isNotLock = CacheUtils.isNotLock(key, loands);
				if (isNotLock) {
					// 先将这个key设置过期时间
					CacheUtils.setExpire(key, 60);
					// 先判断这个loanId是否为p05状态
					McamLoanApplyInfoDTO mcamLoanApplyInfoDTO = iMcamLoanApplyInfoDao
							.selectMcamLoanApplyInfoByLoanId(loanId);
					if (mcamLoanApplyInfoDTO == null || !"P05".equalsIgnoreCase(mcamLoanApplyInfoDTO.getStatus())) {
						continue;
					}
					// 先看放款申请表中这个loanId 且状态是F0(申请)的信息是否存在
					McfeLendingProcess mcfeLendingProcess = consumerFinancialApi.selectByloanIdAndStatus(loanId, "F0");
					if (mcfeLendingProcess != null) {
						continue;
					}
					if (loanApplyRecord(mcamLoanApplyInfoDTO) < 1) {
						continue;
					}
					// 记录操作日志
					loanApplyRecordLog(mcamLoanApplyInfoDTO);

					// 更新进件表中的状态为放款中 F03
//					McamLoanApplyInfoDTO mcamLoanApply = new McamLoanApplyInfoDTO();
//					mcamLoanApply.setStatus(LoanStateConstant.F03);
//					mcamLoanApply.setUpdatedBy(user.getUserName());
//					mcamLoanApply.setUpdatedDate(new Date());
//					mcamLoanApply.setLoanId(mcamLoanApplyInfoDTO.getLoanId());
//					mcamLoanApply.setOldStatus(LoanStateConstant.P05);// 原状态
//					iMcamLoanApplyInfoDao.updateByLoanId(mcamLoanApply);
					MarvelsLogUtil.getInstance().info(">>>>>loanId:"+loanId+",放款申请修改进件状态开始");
					mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(mcamLoanApplyInfoDTO.getLoanId(), LoanStateConstant.F03,LoanStateConstant.P05,user==null?"system":user.getUserCode());
					MarvelsLogUtil.getInstance().info(">>>>>loanId:"+loanId+",放款申请修改进件状态开始");
				}
			} catch (Exception e) {
				MarvelsLogUtil.getInstance().error(">>>>>loanId:" + loanId + ",放款申请异常:", e);
				throw new MarvelsBusinessException(loanId + "申请放款处理异常");
			} finally {
				if (!CacheUtils.isNotLock(key, loands)) {// 如果是锁住的将所释放
					CacheUtils.del(key);
				}
			}
		}
		return MarvelsResultDTO.getResult(MarvelsErrorCode.SUCCESS.getValue(), "申请放款处理成功", null);
	}

	
	
	/**
	 * 记录放款申请表
	 * @param user
	 * @param mcamLoanApplyInfoDTO
	 */
	public int loanApplyRecord( McamLoanApplyInfoDTO mcamLoanApplyInfoDTO) throws Exception{
		// 记录进入放款申请表
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().info(">>>>>>获取用户token为空");
		}
		
		MarvelsLogUtil.getInstance().info("放款申请提交-loanApplyRecord the param ===>"+JSON.toJSONString(mcamLoanApplyInfoDTO));
		McfeLendingProcess mcfeProcess = new McfeLendingProcess();
		mcfeProcess.setCreatedBy(user==null?"system":user.getUserName());
		mcfeProcess.setCreatedDate(new Date());
		mcfeProcess.setUpdatedBy(user==null?"system":user.getUserName());
		mcfeProcess.setUpdatedDate(new Date());
		mcfeProcess.setLoanId(mcamLoanApplyInfoDTO.getLoanId());
		mcfeProcess.setCustCardNo(mcamLoanApplyInfoDTO.getCustCardNo());
		mcfeProcess.setProductType(mcamLoanApplyInfoDTO.getProductType());
		mcfeProcess.setProductTypeName(mcamLoanApplyInfoDTO.getProductTypeName());
		mcfeProcess.setProductCode(mcamLoanApplyInfoDTO.getProductCode());
		mcfeProcess.setProductName(mcamLoanApplyInfoDTO.getProductName());
		mcfeProcess.setPrincipalAmtAct(mcamLoanApplyInfoDTO.getPrincipalAmtAct());
		
		String fundSoure = StringUtils.isEmpty(mcamLoanApplyInfoDTO.getFundCode()) ?"8" :mcamLoanApplyInfoDTO.getFundCode();
		
		BigDecimal loanAmount =mcamLoanApplyInfoDTO.getPrincipalAmtAct();// 借款金额
		LoanAfterInfoDTO loanAfterInfoDTO=new LoanAfterInfoDTO();
		loanAfterInfoDTO.setAmount(loanAmount);//实际借款总额
		loanAfterInfoDTO.setDate(new Date());//放款时间
		loanAfterInfoDTO.setProductCode(mcamLoanApplyInfoDTO.getProductCode());//产品小类code
		loanAfterInfoDTO.setTenor(mcamLoanApplyInfoDTO.getApplyTerms());//期数
		loanAfterInfoDTO.setFundSource(fundSoure);//资金源code
		loanAfterInfoDTO.setLoanId(mcamLoanApplyInfoDTO.getLoanId());//贷款id
		LoanAfterInfoDTO resultInfo=consumerFinancialApi.loanTrial(loanAfterInfoDTO);
		MarvelsLogUtil.getInstance().info("放款申请提交-loanTrial result ===>"+JSON.toJSONString(resultInfo));
		BigDecimal aviAmount= new BigDecimal("0.00");// 到手金额
		BigDecimal interestRate = new BigDecimal("0.00");// 利息费率
		BigDecimal consultingFeeRate = new BigDecimal("0.00");// 咨询费费率
		BigDecimal managementFeeRate = new BigDecimal("0.00");// 管理费费率
		BigDecimal penaltyFeeRate = new BigDecimal("0.00");// 违约金费率
		BigDecimal lateFeeRate = new BigDecimal("0.00");// 滞纳金费率
		BigDecimal preTerminateFeeRate = new BigDecimal("0.00");// 提前结清费费率
		BigDecimal miscFeeRate = new BigDecimal("0.00");// 杂费费率
		BigDecimal platformFeeRate = new BigDecimal("0.00");// 平台费费率
		BigDecimal fundInterestRate = new BigDecimal("0.00");// 资金源利息费率
		if(null !=resultInfo && null!=resultInfo.getFeeRateDTO()){
			FeeRateDTO feeRateDTO=resultInfo.getFeeRateDTO();
			aviAmount = resultInfo.getAviAmount();// 到手金额
			interestRate = feeRateDTO.getInterestRate();// 利息费率
			consultingFeeRate =feeRateDTO.getConsultingFeeRate();// 咨询费费率
			managementFeeRate = feeRateDTO.getManagementFeeRate();// 管理费费率
			penaltyFeeRate =feeRateDTO.getPenaltyFeeRate();// 违约金费率
			lateFeeRate = feeRateDTO.getLateFeeRate();// 滞纳金费率
			preTerminateFeeRate = feeRateDTO.getPreTerminateFeeRate();// 提前结清费费率
			miscFeeRate = feeRateDTO.getMiscFeeRate();// 杂费费率
			platformFeeRate = feeRateDTO.getPlatformFeeRate();// 平台费费率
			fundInterestRate = feeRateDTO.getFundInterestRate();// 资金源利息费率
		}
		BigDecimal consultingFee = loanAmount.subtract(aviAmount);
		mcfeProcess.setAviAmount(aviAmount);
		mcfeProcess.setConsultingFee(consultingFee);
		mcfeProcess.setTerms(mcamLoanApplyInfoDTO.getApplyTerms());
		mcfeProcess.setLoanTime(new Date());
		mcfeProcess.setFundSource(Integer.parseInt(fundSoure));
		mcfeProcess.setFundName(mcamLoanApplyInfoDTO.getFundName());
		mcfeProcess.setChannelCode(mcamLoanApplyInfoDTO.getChannel());
		mcfeProcess.setChannelName(mcamLoanApplyInfoDTO.getChannelName());
		mcfeProcess.setStatus(LoanStateConstant.F0);// F0申请，F1:拒绝 , F2代付成功，F3代付失败，F4手动付款成功，F5非代付审批通过,F6取消 , F7支付中,F10处理中  ,F11更换资金源,F12放款成功
		mcfeProcess.setPaymentBankHead(mcamLoanApplyInfoDTO.getPaymentBankHead());
		mcfeProcess.setPaymentBankBranch(mcamLoanApplyInfoDTO.getPaymentBankBranch());
		mcfeProcess.setPaymentBankName(mcamLoanApplyInfoDTO.getPaymentBankName());
		mcfeProcess.setPaymentAcctName(mcamLoanApplyInfoDTO.getPaymentAcctName());
		mcfeProcess.setPaymentAcctNo(mcamLoanApplyInfoDTO.getPaymentAcctNo());
		mcfeProcess.setReceiveBankHead(mcamLoanApplyInfoDTO.getReceiveBankHead());
		mcfeProcess.setReceiveBankBranch(mcamLoanApplyInfoDTO.getReceiveBankBranch());
		mcfeProcess.setReceiveBankName(mcamLoanApplyInfoDTO.getReceiveBankName());
		mcfeProcess.setReceiveAcctName(mcamLoanApplyInfoDTO.getReceiveAcctName());
		mcfeProcess.setReceiveAcctNo(mcamLoanApplyInfoDTO.getReceiveAcctNo());
		mcfeProcess.setCustName(mcamLoanApplyInfoDTO.getCustName());
		mcfeProcess.setCustMobile(mcamLoanApplyInfoDTO.getMobileNo());
		mcfeProcess.setEmployeeId(mcamLoanApplyInfoDTO.getEmployeeId());
		mcfeProcess.setInterestRate(interestRate);// 利息费率
		mcfeProcess.setConsultingFeeRate(consultingFeeRate);// 咨询费费率
		mcfeProcess.setManagementFeeRate(managementFeeRate);// 管理费费率
		mcfeProcess.setPenaltyFeeRate(penaltyFeeRate);// 违约金费率
		mcfeProcess.setLateFeeRate(lateFeeRate);// 滞纳金费率
		mcfeProcess.setPreTerminateFeeRate(preTerminateFeeRate);// 提前结清费费率
		mcfeProcess.setMiscFeeRate(miscFeeRate);// 杂费费率
		mcfeProcess.setPlatformFeeRate(platformFeeRate);// 平台费费率
		mcfeProcess.setFundInterestRate(fundInterestRate);// 资金源利息费率
		mcfeProcess.setReqNo(GenerateReqNoUtils.transctionReq("DF"));//生成请求编号
		mcfeProcess.setApplyTime(mcamLoanApplyInfoDTO.getApplyTime());
		mcfeProcess.setEmployeeName(mcamLoanApplyInfoDTO.getEmployeeName());
		mcfeProcess.setEmployeeId(mcamLoanApplyInfoDTO.getEmployeeId());
		mcfeProcess.setChannelCodeLvOne(mcamLoanApplyInfoDTO.getChannelCodeLvOne());
		mcfeProcess.setChannelNameLvOne(mcamLoanApplyInfoDTO.getChannelNameLvOne());
		mcfeProcess.setChannelCodeLvTwo(mcamLoanApplyInfoDTO.getChannelCodeLvTwo());
		mcfeProcess.setChannelNameLvTwo(mcamLoanApplyInfoDTO.getChannelNameLvTwo());
		mcfeProcess.setChannelCodeLvThree(mcamLoanApplyInfoDTO.getChannelCodeLvThree());
		mcfeProcess.setChannelNameLvThree(mcamLoanApplyInfoDTO.getChannelNameLvThree());
		mcfeProcess.setPatternCode(mcamLoanApplyInfoDTO.getPatternCode());
		mcfeProcess.setPatternName(mcamLoanApplyInfoDTO.getPatternName());
		
		MarvelsLogUtil.getInstance().info("放款申请提交-loanApplyRecord CALL financial param ===>"+JSON.toJSONString(mcfeProcess));
		int successCount  = consumerFinancialApi.insertLoanAuditInfo(mcfeProcess);

		return successCount;
	}

	
	
	
	/**
	 * 记录操作日志
	 * @param user
	 * @param mcamLoanApplyInfoDTO
	 * @return
	 */
	public int loanApplyRecordLog(McamLoanApplyInfoDTO mcamLoanApplyInfoDTO) throws MarvelsBusinessException{
		// 记录进入放款申请日志表
		int successCount = 0;
		UserDTO user = null;
		try {
			user=CacheUtils.getCacheUser();
		} catch (Exception e) {
			MarvelsLogUtil.getInstance().info(">>>>>>>>>>获取用户token为空");
		}
		McfeLendingProcessLog mcfeLendingProcessLog = new McfeLendingProcessLog();
		mcfeLendingProcessLog.setHandlerUser(user==null?"system":user.getUserName());
		mcfeLendingProcessLog.setStartTime(new Date());
		mcfeLendingProcessLog.setStatus(LoanStateConstant.F0);
		mcfeLendingProcessLog.setCreatedBy(user==null?"system":user.getUserName());
		mcfeLendingProcessLog.setCreatedDate(new Date());
		mcfeLendingProcessLog.setUpdatedBy(user==null?"system":user.getUserName());
		mcfeLendingProcessLog.setUpdatedDate(new Date());
		mcfeLendingProcessLog.setPathStatus("放款申请");
		mcfeLendingProcessLog.setLoanId(mcamLoanApplyInfoDTO.getLoanId());
		successCount = consumerFinancialApi.insertLoanAuditLogInfo(mcfeLendingProcessLog);
		return successCount;
	}
	
	
	
}
